FromIterator trait
https://doc.rust-lang.org/std/iter/trait.FromIterator.html
gpt-5.icon
collect() の裏側で動いている中核トレイトです。
FromIterator トレイトとは
一言で:
Iterator から「自分の型」を組み立てるためのトレイト
定義はこうです:
code:rust
pub trait FromIterator<A>: Sized {
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}
意味を分解すると:
A:要素の型
iter:A を吐く Iterator
Self:出来上がるコレクション
つまり:
「A の列を受け取って、自分自身を作れ」
という契約です。
.collect() との関係(超重要)
code:rust
iter.collect::<Vec<i32>>()
内部では実際こう呼ばれています:
code:rust
Vec::<i32>::from_iter(iter)
つまり:
collect() はただの薄いラッパ
code:text
collect::<B>() == B::from_iter(...)
です。
だから:
Vec
HashMap
Result
Option
などが collect できるのは、
👉 それらが FromIterator を実装しているから
例:Vec の場合
概念的にはこんな感じ:
code:rust
impl<T> FromIterator<T> for Vec<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut v = Vec::new();
for x in iter {
v.push(x);
}
v
}
}
つまり:
空 Vec 作る
回す
push
完成
超素直。
Result / Option が特別に強い理由
これ:
code:rust
let r: Result<Vec<_>, _> = iter.map(...).collect();
なぜ動く?
理由:
code:rust
impl<T, E> FromIterator<Result<T, E>> for Result<Vec<T>, E>
が存在するから。
中身は概念的に:
code:rust
for item in iter {
match item {
Ok(v) => push,
Err(e) => return Err(e),
}
}
Ok(vec)
つまり:
👉 最初の Err で即 return
これが:
validation
parse
IO 前処理
で異常に便利になる理由。
Option も同じ構造。
自作型にも実装できる
例えば:
code:rust
struct Sum(i32);
impl FromIterator<i32> for Sum {
fn from_iter<T: IntoIterator<Item = i32>>(iter: T) -> Self {
Sum(iter.into_iter().sum())
}
}
すると:
code:rust
let s: Sum = vec!1,2,3.into_iter().collect();
が成立します。
つまり:
collect のターゲットを自分で定義できる